import { Injectable } from '@nestjs/common';
import { ConfigService } from '@nestjs/config';
import { ConfigModule } from '@nestjs/config';
import { DbEntityList } from '@/db/db.service';
import {
  TypeOrmModuleOptions,
  TypeOrmModuleAsyncOptions,
} from '@nestjs/typeorm';
import { CacheModuleOptions, CacheStore } from '@nestjs/cache-manager';
import { redisStore, RedisStore } from 'cache-manager-redis-store';
import {
  ServeStaticModuleAsyncOptions,
  ServeStaticModuleOptions,
} from '@nestjs/serve-static';
import * as path from 'path';
import IConstants from '@/core/constants';

@Injectable()
export class AppService {}

export function buildTypeormModuleConfig(): TypeOrmModuleAsyncOptions {
  return {
    imports: [ConfigModule],
    inject: [ConfigService],
    useFactory: function typeormFactoryFunc(
      configService: ConfigService,
    ): TypeOrmModuleOptions {
      const baseConfig = {
        entities: [...DbEntityList],
        synchronize: true,
        logging: false,
        // logging: process.env.RUNNING_ENV === 'development'
      };
      const mysqlConfig: TypeOrmModuleOptions = {
        type: 'mysql',
        host: configService.get('MYSQL_HOST'), // 数据库ip地址
        port: configService.get('MYSQL_PORT'), // 端口
        username: configService.get('MYSQL_USER'), // 登录名
        password: configService.get('MYSQL_PWD'), // 密码
        database: configService.get('MYSQL_DATABASE'), // 数据库名称
        ...baseConfig,
      };
      const sqliteConfig: TypeOrmModuleOptions = {
        type: 'sqlite',
        database: configService.get('SQLITE_DATABASE'),
        ...baseConfig,
      };
      return configService.get('DATABASE_TYPE') === 'mysql'
        ? mysqlConfig
        : sqliteConfig;
    },
  };
}

export function buildCacheModuleConfig(): CacheModuleOptions {
  return {
    isGlobal: true,
    imports: [ConfigModule],
    inject: [ConfigService],
    useFactory: async function (configService: ConfigService) {
      const redisUrl: string = configService.get('REDIS_URL', '');
      if (!redisUrl) return {};
      const store: RedisStore = await redisStore({
        url: configService.get('REDIS_URL'),
        ttl: 60 * 1000,
      });
      return {
        store: store as unknown as CacheStore,
      };
    },
  };
}

export function buildServeStaticConfig(): ServeStaticModuleAsyncOptions {
  return {
    isGlobal: true,
    imports: [ConfigModule],
    inject: [ConfigService],
    useFactory: function (
      configService: ConfigService,
    ): ServeStaticModuleOptions[] {
      return [
        {
          rootPath: IConstants.publicDir,
          serveRoot: '/' + configService.get('STATIC_PREFIX', 'static'),
        },
      ];
    },
  };
}
